﻿using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Threading;
using System.Timers;

namespace SpriteEditor
{
    public partial class frmMain
    {
        //Common updating
        public void refreshModuleGrid()
        {
            dataGridView_Modules.DataSource = null;
            if (spr.lst_Modules != null && spr.lst_Modules.Count > 0)
                dataGridView_Modules.DataSource = spr.lst_Modules;
            dataGridView_Modules.Refresh();
        }

        public void setCurrentModuleOnGrid(int curIndex)
        {
            if (dataGridView_Modules.Rows.Count > curIndex)
            {
                dataGridView_Modules.ClearSelection();
                dataGridView_Modules.CurrentCell = dataGridView_Modules.Rows[curIndex].Cells[0];
                dataGridView_Modules.Rows[curIndex].Selected = true;
                updateCurModuleSelection();
            }
        }

        private void updateCurModuleSelection()
        {
            //if (isUndoRedo)
            //    return;

            if (dataGridView_Modules.DataSource != null
                && dataGridView_Modules.CurrentRow != null 
                && dataGridView_Modules.CurrentRow.Cells[0] != null
                && dataGridView_Modules.CurrentRow.Cells[0].Value != null
                && spr != null && spr.lst_Modules != null && spr.lst_Modules.Count > 0)
            {
                if ((spr.lst_Modules[dataGridView_Modules.CurrentRow.Index].isImageType() && checkBox_DrawImages.Checked)
                    || (spr.lst_Modules[dataGridView_Modules.CurrentRow.Index].isNoneImageType() && checkBox_DrawNoneImages.Checked))
                {
                    if (CurSel_Module == null)
                        CurSel_Module = new ModuleSelection();

                    CurSel_Module.CurrentModuleIndex = ((int)dataGridView_Modules.CurrentRow.Cells[0].Value);
                    CurSel_Module.P1 = new Point(spr.lst_Modules[dataGridView_Modules.CurrentRow.Index].X, spr.lst_Modules[dataGridView_Modules.CurrentRow.Index].Y);
                    CurSel_Module.P2 = new Point(spr.lst_Modules[dataGridView_Modules.CurrentRow.Index].X + spr.lst_Modules[dataGridView_Modules.CurrentRow.Index].W,
                                                 spr.lst_Modules[dataGridView_Modules.CurrentRow.Index].Y + spr.lst_Modules[dataGridView_Modules.CurrentRow.Index].H);
                }
                else
                {
                    CurSel_Module = null;
                }
            }
            else
            {
                CurSel_Module = null;
            }
        }

        public void updateModulesGridFromCurSel_Module()
        {
            bModuleUpdateSelection = false;
            if (CurSel_Module != null)
            {
                dataGridView_Modules.ClearSelection();
                dataGridView_Modules.CurrentCell = dataGridView_Modules.Rows[CurSel_Module.CurrentModuleIndex].Cells[0];
                dataGridView_Modules.Rows[CurSel_Module.CurrentModuleIndex].Selected = true;
            }
            dataGridView_Modules.Refresh();
        }

        //Load image button click
        private void LoadImage()
        {
            if (openFileDialog_LoadImage.ShowDialog() == DialogResult.OK)
            {
                if (File.Exists(openFileDialog_LoadImage.FileName))
                {
                    RemoveAll();
                    ReFreshAll();
                    FillDefautData();

                    spr.spr_image_FileName = openFileDialog_LoadImage.FileName;
                    textBox_Filename.Text = spr.spr_image_FileName;

                    Image tmp_img = Image.FromFile(spr.spr_image_FileName);
                    spr.spr_image = new Bitmap(tmp_img);
                    tmp_img.Dispose();

                    this.Refresh();
                }
                else
                {
                    MessageBox.Show("Image File is not found!!!");
                }
            }
        }

        //Save image button click
        private void SaveImage()
        {
            if (spr.spr_image == null)
                return;

            if (saveFileDialog_SaveImage.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    if (saveFileDialog_SaveImage.FilterIndex == 1)
                    {
                        spr.spr_image.Save(saveFileDialog_SaveImage.FileName, System.Drawing.Imaging.ImageFormat.Png);
                    }
                    else if (saveFileDialog_SaveImage.FilterIndex == 2)
                    {
                        spr.spr_image.Save(saveFileDialog_SaveImage.FileName, System.Drawing.Imaging.ImageFormat.Jpeg);
                    }
                    else if (saveFileDialog_SaveImage.FilterIndex == 3)
                    {
                        spr.spr_image.Save(saveFileDialog_SaveImage.FileName, System.Drawing.Imaging.ImageFormat.Bmp);
                    }
                    spr.spr_image_FileName = saveFileDialog_SaveImage.FileName;
                    textBox_Filename.Text = spr.spr_image_FileName;
                }
                catch (System.Runtime.InteropServices.ExternalException)
                {
                    MessageBox.Show("Can not save!!!");
                }
            }
        }

        //Transparent image button click
        private void transparentImage()
        {
            if (spr.spr_image == null)
                return;

            if (colorDialog.ShowDialog() == DialogResult.OK)
            {
                spr.spr_image.MakeTransparent(colorDialog.Color);
                //SaveImage();
                //try
                //{
                //    spr.spr_image.Save(spr.spr_image_FileName, spr.spr_image.RawFormat);
                //}
                //catch (System.Runtime.InteropServices.ExternalException)
                //{
                //    MessageBox.Show("Can not save!!!");
                //}

                this.Refresh();
            }
        }

        //Add module button click
        public void newModule()
        {
            if (spr != null && spr.spr_image != null)
            {
                spr.newModule();

                refreshModuleGrid();
                setCurrentModuleOnGrid(dataGridView_Modules.Rows.Count-1);
                DrawPanelModule();
                //saveModuleTask();
            }
        }

        //Delete module button click
        public void deleteModule()
        {
            if (dataGridView_Modules.DataSource != null
                && dataGridView_Modules.CurrentRow != null
                && spr != null && spr.lst_Modules != null
                && dataGridView_Modules.Rows.Count > 0
                )
            {
                spr.removeModuleAtIndex(dataGridView_Modules.CurrentRow.Index);

                refreshModuleGrid();
                DrawPanelModule();
                //saveModuleTask();
            }
        }

        //Clone module button click
        public void cloneModule()
        {
            if (spr != null && spr.lst_Modules != null
                && dataGridView_Modules.DataSource != null
                && dataGridView_Modules.CurrentRow != null
                && dataGridView_Modules.Rows.Count > 0)
            {
                int currentIdex = dataGridView_Modules.CurrentRow.Index;
                spr.cloneModuleAtIndex(currentIdex);

                refreshModuleGrid();
                setCurrentModuleOnGrid(currentIdex + 1);
                DrawPanelModule();
                //saveModuleTask();
            }

        }

        //Up module button click
        public void upModule()
        {
            if (spr != null && spr.lst_Modules != null && spr.lst_Modules.Count >= 2
                && dataGridView_Modules.DataSource != null
                && dataGridView_Modules.CurrentRow != null
                && dataGridView_Modules.Rows.Count >= 2)
            {
                int currentRow = dataGridView_Modules.CurrentRow.Index;
                if (currentRow > 0)
                {
                    spr.upModuleAtIndex(currentRow);

                    refreshModuleGrid();
                    setCurrentModuleOnGrid(currentRow - 1);
                    DrawPanelModule();
                    //saveModuleTask();
                }
            }
        }

        //Down module button click
        public void downModule()
        {
            if (spr != null && spr.lst_Modules != null && spr.lst_Modules.Count >= 2
                && dataGridView_Modules.DataSource != null
                && dataGridView_Modules.CurrentRow != null
                && dataGridView_Modules.Rows.Count >= 2)
            {
                int currentRow = dataGridView_Modules.CurrentRow.Index;
                if (currentRow < dataGridView_Modules.Rows.Count - 1)
                {
                    spr.downModuleAtIndex(currentRow);

                    refreshModuleGrid();
                    setCurrentModuleOnGrid(currentRow + 1);
                    DrawPanelModule();
                    //saveModuleTask();
                }
            }
        }

        public void changeModuleType(int newType)
        {
            if (spr != null && spr.lst_Modules != null
                && spr.lst_Modules.Count > dataGridView_Modules.CurrentRow.Index)
            {
                spr.setModuleTypeAtIndex(dataGridView_Modules.CurrentRow.Index, newType);

                refreshModuleGrid();
                updateCurModuleSelection();
                DrawPanelModule();
            }
        }

        //Draw module panel
        private void DrawPanelModule()
        {
       		drawStatusBar();
            if (bufferBitmap == null || panel_Modules.Width != bufferBitmap.Width || panel_Modules.Height != bufferBitmap.Height)
            {
                if (panel_Modules.Width > 0 && panel_Modules.Height > 0)
                    bufferBitmap = new Bitmap(panel_Modules.Width, panel_Modules.Height);
            }
            Graphics g_main = panel_Modules.CreateGraphics();
            Graphics g = Graphics.FromImage(bufferBitmap);
            //bufferBitmap.
            g.ScaleTransform(m_ZoomInModule, m_ZoomInModule);
            g.Clear(panel_Modules.BackColor);

            if (spr != null && spr.spr_image != null && root_Modules_Grid_Pos != null)
            {
                Pen root_pen = new Pen(Color.Brown, 2);
                g.DrawLine(root_pen, new Point(0, root_Modules_Grid_Pos.Y), new Point(panel_Modules.Width, root_Modules_Grid_Pos.Y));
                g.DrawLine(root_pen, new Point(root_Modules_Grid_Pos.X, 0), new Point(root_Modules_Grid_Pos.X, panel_Modules.Height));

                if (checkBox_DrawImages.Checked)
                {
                    g.DrawImage(spr.spr_image, root_Modules_Grid_Pos);

                    if (spr != null && spr.lst_Modules != null)
                    {
                        for (int i = 0; i < spr.lst_Modules.Count; i++)
                        {
                            if (spr.lst_Modules[i].isImageType())
                            {
                                Pen rect_pen = new Pen(Color.Red);
                                rect_pen.DashStyle = DashStyle.Dot;

                                g.DrawRectangle(rect_pen, SpriteCalculation.ConvertToRoot(new Rectangle(spr.lst_Modules[i].X, spr.lst_Modules[i].Y, spr.lst_Modules[i].W, spr.lst_Modules[i].H), root_Modules_Grid_Pos));
                                int m_error = CheckModuleImagesError(i);
                                if (m_error == 1)
                                {
                                    g.DrawString("Outside image", new Font(new FontFamily("Arial"), 12), new SolidBrush(Color.Red), new Point(10, 10));
                                }
                                else if (m_error == 2)
                                {
                                    g.DrawString("Invalid size", new Font(new FontFamily("Arial"), 12), new SolidBrush(Color.Red), new Point(10, 10));
                                }
                                else if (m_error == -1)
                                {
                                    g.DrawString("Null image", new Font(new FontFamily("Arial"), 12), new SolidBrush(Color.Red), new Point(10, 10));
                                }
                            }
                        }
                    }
                }

                if (checkBox_DrawNoneImages.Checked)
                {
                    if (spr != null && spr.lst_Modules != null)
                    {
                        for (int i = 0; i < spr.lst_Modules.Count; i++)
                        {
                            if (spr.lst_Modules[i].isRectType())
                            {
                                Pen rect_pen = new Pen(Color.FromArgb(spr.lst_Modules[i].getColor()));

                                g.DrawRectangle(rect_pen, SpriteCalculation.ConvertToRoot(new Rectangle(spr.lst_Modules[i].X, spr.lst_Modules[i].Y, spr.lst_Modules[i].W, spr.lst_Modules[i].H), root_Modules_Grid_Pos));
                            }
                            else if (spr.lst_Modules[i].isFillRectType())
                            {
                                SolidBrush fillrect_brush = new SolidBrush(Color.FromArgb(spr.lst_Modules[i].getColor()));

                                g.FillRectangle(fillrect_brush, SpriteCalculation.ConvertToRoot(new Rectangle(spr.lst_Modules[i].X, spr.lst_Modules[i].Y, spr.lst_Modules[i].W, spr.lst_Modules[i].H), root_Modules_Grid_Pos));
                            }
                        }
                    }
                }

                if (modules_editor_mode == PANEL_EDIT_RECT_MODE && CurSel_Module != null)
                {
                    if ((spr.lst_Modules[CurSel_Module.CurrentModuleIndex].isImageType() && checkBox_DrawImages.Checked)
                        || (spr.lst_Modules[CurSel_Module.CurrentModuleIndex].isNoneImageType() && checkBox_DrawNoneImages.Checked))
                    {
                        Pen rect_pen = new Pen(Color.Blue);
                        g.DrawRectangle(rect_pen, SpriteCalculation.ConvertToRoot(new Rectangle(CurSel_Module.P1.X, CurSel_Module.P1.Y, CurSel_Module.P2.X - CurSel_Module.P1.X, CurSel_Module.P2.Y - CurSel_Module.P1.Y), root_Modules_Grid_Pos));
                    }
                }
            }
            g_main.DrawImage(bufferBitmap, 0, 0);
        }

        public int CheckModuleImagesError(int idx)
        {
            if (spr != null && spr.spr_image != null && spr.lst_Modules != null && spr.lst_Modules[idx] != null)
            {
                if (spr.lst_Modules[idx].W <= 0 || spr.lst_Modules[idx].H <= 0)
                {
                    //Invalid size
                    return 2;
                }

                if (spr.lst_Modules[idx].X < 0 || spr.lst_Modules[idx].Y < 0
                    || spr.lst_Modules[idx].X + spr.lst_Modules[idx].W > spr.spr_image.Width
                    || spr.lst_Modules[idx].Y + spr.lst_Modules[idx].H > spr.spr_image.Height)
                {
                    //Outside image
                    return 1;
                }
                return 0;
            }
            return -1;
        }
    }
}